// 分页类
class Pagination {
  constructor(selector, opt = {}) {
    // 判断selector是否有值
    if (!selector) throw new Error('必须传递分页容器选择器');
    // 获取页面的分页容器元素
    this.root = document.querySelector(selector);
    if (!this.root) throw new Error('获取分页容器失败,传入选择器有误');
    // 分页配置信息--->后续通过方法设置
    this.info = {};
    // 待创建的元素
    this.first = null;
    this.prev = null;
    this.ulBox = null;
    this.next = null;
    this.last = null;
    this.inp = null;
    this.btn = null;

    // 调用方法
    this.setOpt(opt);
    this.setRoot();
    this.createEle();
    this.render();
    this.bindEvent();
  }
  setOpt(options) { // 设置分页配置信息
    // 设置分页配置的默认值
    // 当前页默认值
    this.info.current = options.current ? options.current : 1;

    // 一页显示数据条数
    this.info.pageSize = options.pageSize ? options.pageSize : 10;

    // 判断是否传递总页数
    if (options.totalPage) {
      this.info.totalPage = options.totalPage;
    } else { // 没有传递总页数
      // 判断是否传递总数据条数
      if (options.total) { // 计算总页数
        this.info.totalPage = Math.ceil(options.total / this.info.pageSize)
      } else {
        this.info.totalPage = 16; // 默认16页
      }
    }
    // 如果当前页大于总页数则 默认当前页为1
    this.info.current = this.info.current > this.info.totalPage ? 1 : this.info.current;

    if (options.change && typeof (options.change) != 'function') throw new Error('change只能是函数');

    // 切换页码 执行函数 默认值
    this.info.change = options.change ? options.change : () => { };


    // 首页,上一页配置默认值
    this.info.first = options.first ? options.first : "首页";
    this.info.prev = options.prev ? options.prev : "上一页";
  }
  setRoot() { // 设置容器样式
    this.setStyle(this.root, {
      width: '1000px',
      height: '40px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontSize: '16px'
      // margin: '50px auto',
      // border: '1px solid #000'
    })

  }
  createEle() {
    // 创建DOM元素并追加到分页容器中
    // 创建一个p标签的 原始元素
    let origin = document.createElement('p');
    this.setStyle(origin, {
      padding: '5px 10px',
      border: '1px solid #eee',
      cursor: 'pointer',
      margin: '0px 10px',
      backgroundColor: '#fff',
      borderRadius: '4px;',
    })
    // 首页按钮===>克隆origin
    this.first = origin.cloneNode(true);
    this.first.innerHTML = this.info.first;
    this.first.className = 'first';// 后续方便点击事件委托
    this.root.appendChild(this.first);
    // 上一页按钮
    this.prev = origin.cloneNode(true);
    this.prev.innerHTML = this.info.prev;
    this.prev.className = 'prev';// 后续方便点击事件委托
    this.root.appendChild(this.prev);

    // 分页页码盒子
    this.ulBox = document.createElement('ul');
    this.setStyle(this.ulBox, {
      display: "flex",
      padding: '0px'
    })
    this.root.appendChild(this.ulBox);

    // 下一页按钮
    this.next = origin.cloneNode(true);
    this.next.innerHTML = '下一页';
    this.next.className = 'next';
    this.root.appendChild(this.next);

    // 尾页按钮
    this.last = origin.cloneNode(true);
    this.last.innerHTML = '尾页';
    this.last.className = 'last';
    this.root.appendChild(this.last);

    // 输入框
    this.inp = document.createElement('input');
    this.setStyle(this.inp, {
      width: '50px',
      height: '30px',
      textAlign: 'center',
      outline: 'none',
      margin: '0px 10px',
      border: '1px solid #eee',
      borderRadius: '4px',
    })
    this.inp.className = 'inp';
    this.root.appendChild(this.inp);

    // 跳转按钮
    this.btn = document.createElement('button');
    this.setStyle(this.btn, {
      width: '50px',
      height: '34px',
      cursor: 'pointer',
      backgroundColor: '#fff',
      border: '1px solid #eee',
    })
    this.btn.innerHTML = '跳转';
    this.btn.className = 'btn';
    this.root.appendChild(this.btn);
  }
  render() {
    // 解构获取当前页, 总页数
    let { current, totalPage } = this.info;
    // 准备禁用样式对象
    let notAllow = { cursor: 'not-allowed', color: '#d2d2d2' }
    let allow = { cursor: 'pointer', color: '#000' }
    // 根据当前页 判断是否 设置 上一页,首页禁用
    if (current === 1) {
      this.setStyle(this.prev, notAllow);
      this.setStyle(this.first, notAllow);
    } else {
      this.setStyle(this.prev, allow);
      this.setStyle(this.first, allow);
    }
    // 根据当前页 判断是否 设置 下一页,尾页禁用
    if (current === totalPage) {
      this.setStyle(this.next, notAllow);
      this.setStyle(this.last, notAllow);
    } else {
      this.setStyle(this.next, allow);
      this.setStyle(this.last, allow);
    }
    // 输入框中渲染 页码数
    this.inp.value = current;
    // 调用渲染具体页码的方法
    this.bindUl();

    // 页码渲染完毕后调用 change函数
    this.info.change({ current, totalPage });
  }
  bindUl() {
    // 在渲染页码前将 ul内容清空
    this.ulBox.innerHTML = '';

    // 解构获取当前页, 总页数
    let { current, totalPage } = this.info;
    // 创建一个原始的li标签 元素
    let origin = document.createElement('li');
    this.setStyle(origin, {
      listStyle: 'none',
      border: '1px solid #eee',
      padding: '5px 10px',
      margin: '0px 5px',
      cursor: 'pointer',
      backgroundColor: '#fff',
      color: '#000',
      borderRadius: '4px',
    })
    let originSpan = document.createElement('span');
    originSpan.innerHTML = '...';
    this.setStyle(originSpan, { color: '#000' })


    origin.className = 'item';
    // 准备一个当前页 样式
    let currStyle = { backgroundColor: '#16baaa', color: '#fff', cursor: 'none' }

    // 根据总页数 也当前页的情况 渲染具体页码

    // 总页数小于等于 9
    if (totalPage <= 9) {
      for (let i = 1; i <= totalPage; i++) {
        //克隆li并追加
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        if (i === current) this.setStyle(li, currStyle);
        this.ulBox.appendChild(li);
      }
      return;
    }

    // 当前页 是 前四页
    if (current <= 4) {
      // 先渲染前五个页码
      for (let i = 1; i <= 5; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        if (i === current) this.setStyle(li, currStyle);
        this.ulBox.appendChild(li);
      }
      // 中间省略号
      let span = originSpan.cloneNode(true);
      this.ulBox.appendChild(span);
      // 最后两个页码
      for (let i = totalPage - 1; i <= totalPage; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        this.ulBox.appendChild(li);
      }
      return;
    }
    // 当前页 是 第五页
    if (current == 5) {
      // 先渲染前7个页码
      for (let i = 1; i <= 7; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        if (i === current) this.setStyle(li, currStyle);
        this.ulBox.appendChild(li);
      }
      // 中间省略号
      let span = originSpan.cloneNode(true);;
      this.ulBox.appendChild(span);
      // 最后两个页码
      for (let i = totalPage - 1; i <= totalPage; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        this.ulBox.appendChild(li);
      }
      return;
    }

    // 当前页 倒数前4页
    if (current >= totalPage - 3) {
      // 先渲染前2个页码
      for (let i = 1; i <= 2; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        this.ulBox.appendChild(li);
      }
      // 中间省略号
      let span = originSpan.cloneNode(true);;
      this.ulBox.appendChild(span);
      // 最后两个页码
      for (let i = totalPage - 4; i <= totalPage; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        if (i === current) this.setStyle(li, currStyle);
        this.ulBox.appendChild(li);
      }
      return;
    }

    // 当前页 是 倒数第五页
    if (current == totalPage - 4) {
      // 先渲染前2个页码
      for (let i = 1; i <= 2; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        this.ulBox.appendChild(li);
      }
      // 中间省略号
      let span = originSpan.cloneNode(true);;
      this.ulBox.appendChild(span);
      // 最后两个页码
      for (let i = totalPage - 6; i <= totalPage; i++) {
        let li = origin.cloneNode(true);
        li.innerHTML = i;
        if (i === current) this.setStyle(li, currStyle);
        this.ulBox.appendChild(li);
      }
      return;
    }


    // 当前页 是 中间页
    // 先渲染前2个页码
    for (let i = 1; i <= 2; i++) {
      let li = origin.cloneNode(true);
      li.innerHTML = i;
      this.ulBox.appendChild(li);
    }
    // 中间省略号
    let span = originSpan.cloneNode(true);;
    this.ulBox.appendChild(span);
    // 中间5个页码
    for (let i = current - 2; i <= current + 2; i++) {
      let li = origin.cloneNode(true);
      li.innerHTML = i;
      if (i === current) this.setStyle(li, currStyle);
      this.ulBox.appendChild(li);
    }
    // 中间省略号
    let span1 = originSpan.cloneNode(true);;
    this.ulBox.appendChild(span1);
    // 最后两个页码
    for (let i = totalPage - 1; i <= totalPage; i++) {
      let li = origin.cloneNode(true);
      li.innerHTML = i;
      this.ulBox.appendChild(li);
    }
  }
  bindEvent() {
    // 利用事件委托完成分页的点击事件    
    this.root.onclick = e => {
      let { target } = e;
      let { current, totalPage } = this.info;
      if (target.className == 'first') { // 点击的是首页按钮
        if (current === 1) return;
        this.info.current = 1;
        this.render();// 重新渲染
      }
      if (target.className == 'prev') { // 点击的是上一页按钮
        if (current === 1) return;
        this.info.current--;
        this.render();// 重新渲染
      }
      if (target.className == 'item') { // 点击的是页码按钮
        // 获取点击的页码数        
        this.info.current = target.innerHTML - 0;
        this.render();// 重新渲染
      }
      if (target.className == 'next') { // 点击的是下一页按钮
        if (current === totalPage) return;
        this.info.current++;
        this.render();// 重新渲染
      }
      if (target.className == 'last') { // 点击的是尾页按钮
        if (current === totalPage) return;
        this.info.current = totalPage;
        this.render();// 重新渲染
      }
      if (target.className == 'btn') { // 点击的是跳转按钮
        // 获取输入的页码
        let cur = this.inp.value - 0
        // 如果不是数值,不在范围内,将输入框的内容渲染为之前的当前页
        if (isNaN(cur) || cur < 1 || cur > totalPage) return this.inp.value = current;
        this.info.current = cur;;
        this.render();// 重新渲染
      }
    }
  }
  setStyle(ele, styleObj) { // 批量设置元素样式
    for (let attr in styleObj) {
      ele.style[attr] = styleObj[attr];
    }
  }

}


export default Pagination